<?php
declare (strict_types=1);

namespace app\api\controller;

use app\common\facade\Ali;
use app\common\model\Area;
use app\common\model\BusinessApply as BusinessApplyModel;
use app\common\model\Express;
use app\common\model\OrderLogistics;
use app\common\model\OrderProduct;
use app\common\model\OrderRefund;
use app\common\model\OrderRefundReason;
use app\common\model\Order as OrderModel;
use app\common\model\OrderTemporary;
use app\common\model\ProductEvaluate;
use app\common\model\Business;
use app\common\tool\Result;
use app\common\tool\WeChat\WeChat;
use think\exception\ValidateException;
use think\Response;
use app\common\model\Product;

class Order extends Base
{

    /**
     * @return Response
     * 设置临时下单商品
     */
    public function setTemporary(): Response
    {
        try {
            return Result::fastReturn(OrderTemporary::setTemporary($this->request->post(), $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 获取临时存储下单商品
     */
    public function getTemporary(): Response
    {
        try {
            return Result::fastReturn(OrderTemporary::getTemporary($this->user->id));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @return Response
     * 提交订单
     */
    public function submit(): Response
    {
        try {
            return Result::fastReturn(OrderTemporary::submit($this->request->post(), $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @param $id
     * @return Response
     * 获取待支付的订单
     */
    public function getPayment($id): Response
    {
        try {
            $cate_2 = $this->request->param('cate_2');
            return Result::fastReturn(OrderTemporary::getPayment($id, $this->user,$cate_2));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * 支付方式
     * @param string $cate_1
     * @param string $cate_2
     * @return Response
     */
    public function payWay($cate_1 = '', $cate_2 = ''): Response
    {
        try {
            return Result::success('success', OrderTemporary::payWay($cate_1, true, $cate_2));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @return Response
     * 支付订单
     */
    public function payment(): Response
    {
        try {
            return Result::fastReturn(OrderTemporary::payment($this->request->post(), $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * 订单数量
     * @return Response
     */
    public function orderCount(): Response
    {
        try {
            $category = $this->request->param('category', 1);

            $uid = $this->user->id;
            $obligation = OrderTemporary::where(['uid' => $uid, 'category'=>$category, 'status' => 1])->where('is_del', 0)->count();//待付款
            $shipping = OrderTemporary::where(['uid' => $uid, 'category'=>$category, 'status' => 2])->where('is_del', 0)->count();//待发货
            $receiving = OrderTemporary::where(['uid' => $uid, 'category'=>$category, 'status' => 3])->where('is_del', 0)->count();//待收货
            $evaluating = OrderTemporary::where(['uid' => $uid, 'category'=>$category, 'status' => 4])->where('is_del', 0)->count();//待评价
            $returning = OrderRefund::where(['uid' => $uid, 'is_del' => 0])->count();//退款售后

            $result = [
                'obligation' => $obligation,
                'shipping'   => $shipping,
                'receiving'  => $receiving,
                'evaluating' => $evaluating,
                'returning'  => $returning
            ];
            return Result::success('success', $result);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @return Response
     * 获取我的订单
     */
    public function getMyOrder(): Response
    {
        try {
            $param = $this->request->get();
            $map = [['uid', '=', $this->user->id], ['is_del', '=', 0], ['is_return', '=', 0]];
            if (isset($param['status']) && $param['status']) {
                $map[] = ['status', '=', $param['status']];
            }
            $map[] = ['category', '=', isset($param['category']) && $param['category'] ? $param['category'] : 1];
            $list = OrderTemporary::getPageList($map, 'id,sn,total_amount,real_amount,create_time,is_life,status,data,order_type,order_mode,is_prize', $this->getPage(),
                $this->getLimit(), false, ['productsField']);
            foreach ($list['data'] as &$v) {
                $v->statusCode = $v->getData('status');
                $v->refundStatus = 1;
                if ($v->statusCode == 1) {
                    unset($v->productsField);
                    $v->productsField = OrderTemporary::parseOrderData($v->data);
                } else {
                    $v->productsField->toArray();
                    if (in_array($v->order_type, [1, 2, 3, 5]) || $v->is_prize) {
                        $v->refundStatus = 2;
                    }
                }
                $v->cate_2 = 0;
                if(isset($v->productsField[0]['cate_2'])){
                    $v->cate_2 = $v->productsField[0]['cate_2'];
                }
                unset($v->data);
            }
            return Result::fastReturn($list);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @param $id
     * @return Response
     * 获取订单详情
     */
    public function getMyOrderInfo($id): Response
    {
        try {
            $info = OrderTemporary::where(['uid' => $this->user->id, 'id' => $id, 'is_del' => 0])
                ->withoutField('update_time,is_del')
                ->with(['p', 'c', 'd', 'behalfUser'])
                ->find();
            if (empty($info)) return Result::fail('订单不存在');
            $info->pay_time = $info->pay_time ? date("Y-m-d H:i:s", $info->getData('pay_time')) : '';
            $info->post_time = $info->post_time ? date("Y-m-d H:i:s", $info->getData('post_time')) : '';
            $info->statusCode = $info->getData('status');
            $info->friendlyText = getProductOrderFriendly($info->statusCode);
            if ($info->statusCode == 1) {
                $product = json_decode($info['data'], true)['product'];
                foreach ($product as &$p){
                    $p['business_address_details'] = !isset($p['business_address_details']) ? Business::where('id', $p['business_id'])->value('full_address') : $p['business_address_details'];
                }
                $info->product = $product;
            } else {
                $product[] = [
                    'business_id'           => $info->business_id,
                    'business_remarks'      => $info->remark,
                    'business_title'        => $info->business->title,
                    'business_customer_tel' => $info->business->customer_tel,
                    'business_address_details' => $info->business->full_address,
                    'children'              => $info->productsField->toArray()
                ];
                $info->product = $product;
            }

            if (in_array($info->order_type, [1, 2, 3, 5]) || $info->is_prize) {
                $info->refundStatus = 2;
            } else {
                $info->refundStatus = 1;
            }
            $info->cate_2 = isset($info['product'][0]['children'][0]['pid']) ? Product::where('id', $info['product'][0]['children'][0]['pid'])->value('cate_2') : 0;
            unset($info['data']);
            unset($info->business);
            unset($info->productsField);
            unset($info->remark);
            return Result::success('success', $info);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 订单相关修改
     */
    public function editMyOrder(): Response
    {
        try {
            return Result::fastReturn(OrderTemporary::edit($this->request->post(), $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @return Response
     * 评价前置
     */
    public function evaluateFront($id): Response
    {
        try {
            $info = OrderTemporary::where(['uid' => $this->user->id, 'id' => $id, 'is_del' => 0])
                ->field('id,sn,status,business_id')
                ->find();
            if (empty($info)) return Result::fail('订单不存在');
            if ($info->getData('status') != 4) {
                return Result::fail('该订单已评价或未完成');
            }
            $info->productsField->toArray();
            $info->business->toArray();
            return Result::success('success', $info);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 提交评价
     */
    public function evaluateSave(): Response
    {
        try {
            $param = $this->request->post();
            $this->validate($param, 'ProductEvaluate');
            return Result::fastReturn(ProductEvaluate::evaluateSave($param, $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @param $id - 订单ID
     * @param $children - 订单商品ID
     * @return Response
     * 获取待退款退货的商品
     */
    public function refundFront(): Response
    {
        try {
            $param = $this->request->get();
            $info = OrderTemporary::where(['id' => $param['id'], 'uid' => $this->user->id])->field('id,status,order_type')->find();
            if (empty($info)) {
                return Result::fail('订单错误');
            }
            if (in_array($info->order_type, [1, 2, 3, 5])) {
                return Result::fail('该订单无法申请退款/退款退货~');
            }
            if (!in_array($info->getData('status'), [1, 2, 3, 4, 6])) {
                return Result::fail('该订单无法申请退款/退款退货~~');
            }
            $that = OrderProduct::where('order_id', $info->id)->where('return_status', 0);
            if (isset($param['children']) && $param['children']) {
                $that->whereIn('id', $param['children']);
            }
            $product = $that->field('id,order_id,pid,title,num,sku_name,icon,vip_price')->select();
            $result['productStatus'] = [['id' => 1, 'title' => '未收到货'], ['id' => 2, 'title' => '已收收到货']];
            $result['product'] = $product;
            $result['refundTotal'] = sprintfFloor($that->sum('vip_price'));
            $result['refundReason'] = OrderRefundReason::getList([], true, '', '', 'id,title');
            return Result::success('success', $result);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 申请退款
     */
    public function refundSave(): Response
    {
        try {
            $param = $this->request->post();
            $this->validate($param, 'OrderRefund');
            return Result::fastReturn(OrderRefund::refundSave($param, $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 获取我的退款售后订单
     */
    public function getMyRefundOrder(): Response
    {
        try {
            $param = $this->request->get();
            $map = ['is_del' => 0, 'uid' => $this->user->id];

            $like = [];
            if (isset($param['keyword']) && $param['keyword']) {
                $like = ['field' => 'sn', 'keyword' => $param['keyword']];
            }
            $list = OrderRefund::getPageList($map, 'id,sn,status,total,op_ids,type', $this->getPage(),
                $this->getLimit(), false, '', '', '', $like, '', '', ['product']);

            return Result::fastReturn($list);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @param $id
     * @return Response
     * 我的退款订单详情
     */
    public function getMyRefundOrderInfo($id): Response
    {
        try {
            $info = OrderRefund::where(['id' => $id, 'uid' => $this->user->id, 'is_del' => 0])
                ->withoutField('is_del')
                ->find()->append(['product']);
            if (empty($info)) return Result::fail('订单无效');
            $info->pay_way_raw = $info->getData('pay_way');
            $info->business->toArray();
            $info->real_amount = round($info->total - $info->currency - $info->chain_bean - $info->love_bean - $info->deduct, 2);
            return Result::success('success', $info);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @return Response
     * 用户修改订单信息
     */
    public function editRefundOrder(): Response
    {
        try {
            $param = $this->request->post();
            $this->validate($param, 'OrderRefundExpress');
            return Result::fastReturn(OrderRefund::userEdit($param, $this->user));
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }


    /**
     * @return Response
     * 获取快递
     */
    public function getExpress(): Response
    {
        try {
            return Result::success('success',
                Express::where(['status' => 1, 'is_del' => 0])->field('id,title')->select());
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * 订单物流信息
     * @param $id
     * @param int $is_refund
     * @return Response
     */
    public function orderExp($id, $is_refund = 0): Response
    {
        try {
            if ($is_refund) {
                $order = OrderRefund::where('id', $id)->field('id,express_id,express_code,express_title,op_ids,receiver,receiver_tel,order_id')->find();
                $ops = explode(',', $order['op_ids']);
                $order['products_count'] = count($ops);
                $order['product_icon'] = OrderProduct::where(['order_id' => $id, 'pid' => $ops[0]])->value('icon');
                $order['address_details'] = Business::where('id', $order['business_id'])->value('return_full_address');

                $logistics = [];
            } else {
                $order = OrderTemporary::where('id', $id)->field('id,sn,express_id,express_code,uid,receiver,receiver_tel,province,city,district,address_details')->withCount('products')->find();
                $order['express_title'] = Express::where('id', $order['express_id'])->value('title');
                $order['product_icon'] = OrderProduct::where('order_id', $id)->value('icon');
                $area = Area::where('code', $order['district'])->find();
                $order['address_details'] = $area->province . $area->city . $area->district . $order['address_details'];

                $logistics = OrderLogistics::where('order_id', $id)->field('id,order_id,product_ids,express_id,express_code,express_title')->select()->each(function ($item){
                    $pids = explode(',', $item->product_ids);
                    $item->products_count = count($pids);
                    $item->product_icon = Product::where('id', $pids[0])->value('icon');
                });
            }

            $data = [
                'express_title'  => $order['express_title'],
                'express_code'   => $order['express_code'],
                'products_count' => $order['products_count'],
                'product_icon'   => $order['product_icon'],
                'receiver'       => $order['receiver'],
                'receiver_tel'   => $order['receiver_tel'],
                'address'        => $order['address_details'],
                'logistics'     => $logistics
            ];

            return Result::fastReturn(['code' => 1, 'msg' => 'success', 'data' => $data]);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * @param $id
     * @param int $is_refund
     * @param int $logistics_id
     * @return Response
     */
    public function expInfo($id, $is_refund = 0, $logistics_id = 0): Response
    {
        try {
            if ($is_refund) {
                $order = OrderRefund::where('id', $id)->field('id,express_id,express_code,receiver_tel')->find()->toArray();
            } else {
                $order = OrderModel::where('id', $id)->field('id,express_id,express_code,receiver_tel')->find()->toArray();
                if($logistics_id){
                    if(!$logistics = OrderLogistics::find($logistics_id)){
                        return Result::fail('物流不存在');
                    }
                    $order['express_id'] = $logistics['express_id'];
                    $order['express_code'] = $logistics['express_code'];
                }
            }

            $expType = Express::where('id', $order['express_id'])->value('type');
            $traces = Ali::expInfo($order['express_code'], $expType, $order['receiver_tel']);

            return Result::fastReturn($traces);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * 快递列表（第三方查询快递公司编码时使用）
     * @return Response
     */
    public function expList(): Response
    {
        try {
            $list = Ali::expressList();

            return Result::fastReturn(['code' => 1, 'msg' => 'success', 'data' => $list]);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    /**
     * 小程序订单核销码
     * @return Response
     */
    public function scanCode(): Response
    {
        if (!$write_off_code = $this->request->param('write_off_code', '')) {
            return Result::fail('核销码不能为空');
        }
        if (!$order = OrderTemporary::where('write_off_code', $write_off_code)->find()) {
            return Result::fail('待核销订单不存在');
        }
        $scan_code = $order->scan_code;
        if (!$scan_code) {
            $scene = $this->request->param('scene', '');
            $linkurl = $this->request->param('linkurl', 'pages/index/index');
            $ressult = (new WeChat())->generateScanCode($write_off_code, $linkurl, $scene);
            if ($ressult['code'] == 1) {
                $scan_code = $ressult['data'];
            } else {
                return Result::fail('获取失败');
            }
        }
        return Result::fastReturn(['code' => 1, 'msg' => 'success', 'data' => ['scan_code' => $scan_code]]);
    }


    /**
     * @param $id
     * @return Response
     * 获取代付订单简易信息
     */
    public function getWocInfo($id)
    {
        try {
            $info = OrderTemporary::where(['id' => $id, 'is_del' => 0, 'status' => 1])
                ->withoutField('update_time,is_del')
                ->with(['p', 'c', 'd', 'user'])
                ->find();
            if (empty($info)) return Result::fail('订单不存在或已付款');
            if ($info->uid == $this->user->id) {
                return Result::fail('', [], -2);
            }
            $info->statusCode = $info->getData('status');

            if ($info->statusCode == 1) {
                $info->product = json_decode($info['data'], true)['product'];
            } else {
                $product[] = [
                    'business_id'           => $info->business_id,
                    'business_remarks'      => $info->remark,
                    'business_title'        => $info->business->title,
                    'business_customer_tel' => $info->business->customer_tel,
                    'children'              => $info->productsField->toArray()
                ];
                $info->product = $product;
            }
            unset($info['data']);
            unset($info->business);
            unset($info->productsField);
            unset($info->remark);
            $info->method = OrderTemporary::payWay($info->order_type, false);
//            $info->behalf_uid = $this->user->id;
//            $info->pay_way = 'behalf';
//            $info->save();
            return Result::success('success', $info);
        } catch (\Exception $e) {
            return Result::fail($e->getMessage());
        }
    }

    public function invoiceApply()
    {
        try {
            $param = $this->request->post();
            $this->validate($param, 'InvoiceApply');
            return Result::fastReturn(OrderTemporary::invoiceApply($param, $this->user));
        } catch (ValidateException $e) {
            return Result::fail($e->getMessage());
        } catch (\Exception $e) {
            return Result::fail('加载失败，服务器错误！');
        }

    }

}


